En esta práctica abordamos un caso real de minería de datos donde tenemos que poner en juego todos los conceptos trabajados en la asignatura. Hay que trabajar todo el ciclo de vida del proyecto, desde el objetivo del proyecto hasta la implementación del conocimiento encontrado, pasando por la preparación, limpieza de los datos, conocimiento de los datos, generación del modelo, interpretación y evaluación. La práctica la dividiremos en dos partes. En esta primera parte (PRA1), abordaremos las primeras fases del proceso, desde los objetivos hasta la preparación de los datos, y en la segunda parte (PRA2) seguiremos con el resto del proceso.
El objetivo global de esta primera parte de la práctica (PRA1) consiste en seleccionar uno o varios juegos de datos, y realizar las tareas de preparación y análisis exploratorio con el objetivo de disponer de datos listos para después. En la segunda parte (PRA2), aplicar algoritmos de clustering, regresión o clasificación, demostrando la correcta asimilación de todos los aspectos trabajados durante el semestre.
Las competencias que se trabajan en esta prueba son:
Material docente proporcionado por la UOC.
El formato de entrega es: - fichero output: en formato username_estudiante-PRA1.html/pdf - fichero ejecutable: en formato username_estudiante-PR1.Rmd
Se debe entregar la PRA_1 en el buzón de entregas del aula
A menudo es inevitable, al producir una obra multimedia, hacer uso de recursos creados por terceras personas. Es por lo tanto comprensible hacerlo en el marco de una práctica de los estudios de Informática, Multimedia y Telecomunicación de la UOC, siempre y cuando esto se documente claramente y no suponga plagio en la práctica.
Por lo tanto, al presentar una práctica que haga uso de recursos ajenos, se debe presentar junto con ella un documento en que se detallen todos ellos, especificando el nombre de cada recurso, su autor, el lugar donde se obtuvo y su estatus legal: si la obra esta protegida por el copyright o se acoge a alguna otra licencia de uso (Creative Commons, licencia GNU, GPL …). El estudiante deberá asegurarse de que la licencia no impide específicamente su uso en el marco de la práctica. En caso de no encontrar la información correspondiente tendrá que asumir que la obra esta protegida por copyright.
Deberéis, además, adjuntar los ficheros originales cuando las obras utilizadas sean digitales, y su código fuente si corresponde.
Todo estudio analítico debe nacer de una necesidad por parte del negocio o de una voluntad de dotarle de un conocimiento contenido en los datos y que solo podremos obtener a través de una colección de buenas prácticas basadas en la Minería de Datos.
El mundo de la analítica de datos se sustenta en 3 ejes:
A. Uno de ellos es el profundo conocimiento que deberíamos tener del negocio al que tratamos de dar respuestas mediante los estudios analíticos.
B. El otro gran eje es sin duda las capacidades analíticas que seamos capaces de desplegar y en este sentido, las dos prácticas de esta asignatura pretenden que el estudiante realice un recorrido sólido por este segundo eje.
C. El tercer eje son los Datos. Las necesidades del Negocio deben concretarse con preguntas analíticas que a su vez sean viables responder a partir de los datos de que disponemos. La tarea de analizar los datos es sin duda importante, pero la tarea de identificarlos y obtenerlos va a ser para un analista un reto permanente.
Como primera parte del estudio analítico que nos disponemos a realizar, se pide al estudiante que complete los siguientes pasos:
Plantear un problema de analítica de datos detallando los objetivos analíticos y explica una metodología para resolverlos de acuerdo con lo que se ha practicado en las PEC y lo que se ha aprendido en el material didáctico.
Seleccionar un juego de datos y justificar su elección. El juego de datos deberá tener capacidades para que se le puedan aplicar algoritmos supervisados, algoritmos no supervisados y reglas de asociación y deberá estar alineado con el problema analítico planteado en el paso anterior.
Requisito mínimo: El juego de datos deberá tener como mínimo 500 observaciones con un mínimo de 5 variables numéricas, 2 categóricas y 1 binaria. Además debe ser distinto, es importante que no sea un dataset usado en las PEC anteriores.
Realizar un análisis exploratorio del juego de datos seleccionado.
Realizar tareas de limpieza y acondicionado para poder ser usado en procesos de modelado.
Realizar métodos de discretización
Aplicar un estudio PCA sobre el juego de datos. A pesar de no estar explicado en el material didáctico, se valorará si en lugar de PCA investigáis por vuestra cuenta y aplicáis SVD (Single Value Decomposition).
Para todas las PRA es necesario documentar en cada apartado del ejercicio práctico que se ha hecho, por qué se ha hecho y cómo se ha hecho. Asimismo, todas las decisiones y conclusiones deberán ser presentados de forma razonada y clara, contextualizando los resultados, es decir, especificando todos y cada uno de los pasos que se hayan llevado a cabo para su resolución.
20% Se plantea un problema propio de minería de datos, se detallan los objetivos analíticos y se explica detalladamente el procedimiento para darles solución.
10%. Justificación de la elección del juego de datos donde se detalle el potencial analítico que se intuye. El estudiante deberá visitar los siguientes portales de datos abiertos para seleccionar su juego de datos:
Datos abiertos
Conjuntos de datos para aprendizaje automático e investigación
Recordad que el mismo dataset deberá tener capacidades para que se le puedan aplicar algoritmos supervisados, algoritmos no supervisados y reglas de asociación.
En esta práctica pretendo clasificar en función de su calidad un conjunto de vinos portugueses, tanto tintos como blancos, con denominación de origen “vinho verde”. La clasificación se hará asignado a cada muestra una categorías de calidad. Por tanto se trata de un problema para que que aplicaré un modelo supervisado de clasificación
Estos juegos de datos ya fueron usados en un proyecto que pretendía predecir , dadas una serie de características físico-químicas de las muestras, predecir las preferencias del gusto humano. Ene este enlace se encuentra la descripción del estudio:
https://www.sciencedirect.com/science/article/abs/pii/S0167923609001377?via%3Dihub
Básicamente aplicaron técnicas de regresión y support vector machines , empleando distintos modelos con el objetivo de conseguir predicciones que sirvieran de apoyo a las evaluaciones de la calidad del vino de los enológos y como consecuencia mejorar la productividad de la producción del vino.
Centrándonos en las fuentes de datos, para este proceso contamos con dos juegos de datos, uno de vinos blancos con más de 4900 registros y otro de vinos tintos con unas 1600 muestras. Contiene doce atributos; once son comunas con valores reales que hacen referencia a las características fisico-químicas y la duodécima característica, con valores enteros hace referencia a la calidad del vino. Se trata por tanto de la etiqueta o la variable dependiente del juego de datos, según consideremos clasificación o regresión lineal. Las he tomado de la dirección:
https://archive.ics.uci.edu/ml/datasets/Wine+Quality
Como se aprecia en la descripción , con estos datos se pueden aplicar técnicas de regresión y de clasificación. Siendo la segunda opción por la que vamos a optar.
Las modificaciones que se han hecho para cumplir con los requisitos del enunciado son : -La variable “pH” originalmente tenía valores reales y la he transformado a booleana. - La variable “quality” , de valores enteros que iban de 1 a 10 la he transformado en categórica estableciendo cinco categorías - Para obtener una segunda variable categórica he unido los dos juegos de datos y he añadido una nueva variable, “type” , que indica si el vino es tinto o blanco.
Dado que en este ejercicio voy a utilizar otras técnicas de modelado distintas las que se usaron en aquel proyecto del 2009 y que voy a transformar algunas columnas y la clasificación la efectuara sobre un único dataset fusionado incluyendo vinos tintos y blancos (que como se verá más adelante presentan diferencias en la distribución de las distintas características), lo esperable es plantearse un nivel de cumpliemiento de los objetivos menos ambiciosos. Dado este contexto vamos a plantearnos como objetivo llegar a un nivel de precisión en la clasificación del 85%.
Cargamos los dos archivos cs, los de vinos tintos y los de vinos blancos, en sendos datasets y a continuación mostramos un resumen estadístico de cada columna.
Salvo la columna “quality”, que tiene valores enteros el resto de atributos contienen valores reales.
import pandas as pd
import os
import statistics
import matplotlib.pyplot as plt
import seaborn as sb
import chart_studio.plotly as py
import plotly.graph_objs as go
import numpy as np
from sklearn.decomposition import PCA as sk_pca
from sklearn.preprocessing import StandardScaler
filename = "winequality-red.csv"
filename2 = "winequality-white.csv"
vinos_tintos = pd.read_csv(filename,sep=';')
vinos_blancos = pd.read_csv(filename2,sep=';')
print(vinos_tintos.shape)
## (1599, 12)
print(vinos_blancos.shape)
## (4898, 12)
atributos=vinos_tintos.columns.values
vinos_tintos[atributos[0:4]].describe()
## fixed acidity volatile acidity citric acid residual sugar
## count 1599.000000 1599.000000 1599.000000 1599.000000
## mean 8.319637 0.527821 0.270976 2.538806
## std 1.741096 0.179060 0.194801 1.409928
## min 4.600000 0.120000 0.000000 0.900000
## 25% 7.100000 0.390000 0.090000 1.900000
## 50% 7.900000 0.520000 0.260000 2.200000
## 75% 9.200000 0.640000 0.420000 2.600000
## max 15.900000 1.580000 1.000000 15.500000
vinos_tintos[atributos[4:8]].describe()
## chlorides free sulfur dioxide total sulfur dioxide density
## count 1599.000000 1599.000000 1599.000000 1599.000000
## mean 0.087467 15.874922 46.467792 0.996747
## std 0.047065 10.460157 32.895324 0.001887
## min 0.012000 1.000000 6.000000 0.990070
## 25% 0.070000 7.000000 22.000000 0.995600
## 50% 0.079000 14.000000 38.000000 0.996750
## 75% 0.090000 21.000000 62.000000 0.997835
## max 0.611000 72.000000 289.000000 1.003690
vinos_tintos[atributos[8:12]].describe()
## pH sulphates alcohol quality
## count 1599.000000 1599.000000 1599.000000 1599.000000
## mean 3.311113 0.658149 10.422983 5.636023
## std 0.154386 0.169507 1.065668 0.807569
## min 2.740000 0.330000 8.400000 3.000000
## 25% 3.210000 0.550000 9.500000 5.000000
## 50% 3.310000 0.620000 10.200000 6.000000
## 75% 3.400000 0.730000 11.100000 6.000000
## max 4.010000 2.000000 14.900000 8.000000
vinos_blancos[atributos[0:4]].describe()
## fixed acidity volatile acidity citric acid residual sugar
## count 4898.000000 4898.000000 4898.000000 4898.000000
## mean 6.854788 0.278241 0.334192 6.391415
## std 0.843868 0.100795 0.121020 5.072058
## min 3.800000 0.080000 0.000000 0.600000
## 25% 6.300000 0.210000 0.270000 1.700000
## 50% 6.800000 0.260000 0.320000 5.200000
## 75% 7.300000 0.320000 0.390000 9.900000
## max 14.200000 1.100000 1.660000 65.800000
vinos_blancos[atributos[4:8]].describe()
## chlorides free sulfur dioxide total sulfur dioxide density
## count 4898.000000 4898.000000 4898.000000 4898.000000
## mean 0.045772 35.308085 138.360657 0.994027
## std 0.021848 17.007137 42.498065 0.002991
## min 0.009000 2.000000 9.000000 0.987110
## 25% 0.036000 23.000000 108.000000 0.991723
## 50% 0.043000 34.000000 134.000000 0.993740
## 75% 0.050000 46.000000 167.000000 0.996100
## max 0.346000 289.000000 440.000000 1.038980
vinos_blancos[atributos[8:12]].describe()
## pH sulphates alcohol quality
## count 4898.000000 4898.000000 4898.000000 4898.000000
## mean 3.188267 0.489847 10.514267 5.877909
## std 0.151001 0.114126 1.230621 0.885639
## min 2.720000 0.220000 8.000000 3.000000
## 25% 3.090000 0.410000 9.500000 5.000000
## 50% 3.180000 0.470000 10.400000 6.000000
## 75% 3.280000 0.550000 11.400000 6.000000
## max 3.820000 1.080000 14.200000 9.000000
se observa que no existen valores NA
pd.isnull(vinos_blancos).values.ravel().sum()
## 0
pd.isnull(vinos_tintos).values.ravel().sum()
## 0
Vamos a ayudarnos de histogramas para ver las distribuciones de cada variable y comparar su comportamiento en función del tipo de vino Comenzando con las tres primeras columnas, se aprecia que para “fixed acidity” para los vinos tintos que esta desplazada varias unidades a la derecha y que tienen una asimetría positiva. Para los otros dos atributos las distribuciones no presentan diferencias destacables.
atributos=vinos_blancos.columns
sb.histplot(vinos_blancos[atributos[0:3]],kde=True).set_title('Histograma vinos blancos')
sb.histplot(vinos_tintos[atributos[0:3]],kde=True).set_title('Histograma vinos blancos')
Para “real sugar”, dejando de lado que existen muchas mas muestras para los vinos blancos, destaca que la distribución para los vinos blancos presenta una asimetría positiva muy pronunciada. Para los vinos tintos la desviación sobre la media es mucho menor.
sb.histplot(vinos_blancos[atributos[3]],kde=True).set_title('Histograma "real sugar" vinos blancos(azul) y tintos (rojo)')
sb.histplot(vinos_tintos[atributos[3]],color="red",kde=True)
Pasando a los siguientes tres atributos vemos diferencias en la distribución de “total sulfur dioxide”, la distribución para los vinos blancos tiene un alto grado de simetría y su mediana supera en casi 100 unidades a a la de los vinos vlancos, que presneta una cola derecha muy alargada.
sb.histplot(vinos_blancos[atributos[4:7]],kde=True).set_title('Histograma vinos blancos')
sb.histplot(vinos_tintos[atributos[4:7]],kde=True).set_title('Histograma vinos tintos')
La distribución para “pH” en los vinos blancos la desviación es bastante menor y se encuentra casi dos décimas más a la izquierda.
sb.histplot(vinos_blancos[atributos[8]],kde=True).set_title('Histograma pH vinos blancos(azul) y tintos (rojo)')
sb.histplot(vinos_tintos[atributos[8]],color="red",kde=True)
Para “sulfates” y “alcohol” no se aprecian diferencias reseñables.
sb.histplot(vinos_blancos[atributos[9:11]],kde=True).set_title('Histograma vinos blancos')
sb.histplot(vinos_tintos[atributos[9:11]],kde=True).set_title('Histograma vinos tintos')
Finalmente vemos la variable “quality” que en ambos casos los valores más frecuentes son los centrales. Este gráfico nos servirá como referencia para categorizarla más adelante.
sb.histplot(vinos_blancos["quality"],).set_title('Histograma quality vinos blancos(azul) y tintos (rojo)')
sb.histplot(vinos_tintos["quality"],color="red")
Comenzamos fusionando los dos datasets y creamos la variable “type”
vinos_blancos.insert(0,"type",0)
vinos_tintos.insert(0,"type",1)
vinos=pd.concat([vinos_blancos,vinos_tintos],axis=0,ignore_index=True)
print(vinos.shape)
## (6497, 13)
vinos[atributos[0:4]].describe()
## fixed acidity volatile acidity citric acid residual sugar
## count 6497.000000 6497.000000 6497.000000 6497.000000
## mean 7.215307 0.339666 0.318633 5.443235
## std 1.296434 0.164636 0.145318 4.757804
## min 3.800000 0.080000 0.000000 0.600000
## 25% 6.400000 0.230000 0.250000 1.800000
## 50% 7.000000 0.290000 0.310000 3.000000
## 75% 7.700000 0.400000 0.390000 8.100000
## max 15.900000 1.580000 1.660000 65.800000
vinos[atributos[4:8]].describe()
## chlorides free sulfur dioxide total sulfur dioxide density
## count 6497.000000 6497.000000 6497.000000 6497.000000
## mean 0.056034 30.525319 115.744574 0.994697
## std 0.035034 17.749400 56.521855 0.002999
## min 0.009000 1.000000 6.000000 0.987110
## 25% 0.038000 17.000000 77.000000 0.992340
## 50% 0.047000 29.000000 118.000000 0.994890
## 75% 0.065000 41.000000 156.000000 0.996990
## max 0.611000 289.000000 440.000000 1.038980
vinos[atributos[8:12]].describe()
## pH sulphates alcohol quality
## count 6497.000000 6497.000000 6497.000000 6497.000000
## mean 3.218501 0.531268 10.491801 5.818378
## std 0.160787 0.148806 1.192712 0.873255
## min 2.720000 0.220000 8.000000 3.000000
## 25% 3.110000 0.430000 9.500000 5.000000
## 50% 3.210000 0.510000 10.300000 6.000000
## 75% 3.320000 0.600000 11.300000 6.000000
## max 4.010000 2.000000 14.900000 9.000000
Ahora pasamos a eliminar los outliers. Los valores máximos y mímimos que aparecen en el resumen del nuevo data set nos sugieren que para las variables “residual sugar”, “free sulfur dioxide” y “total sulfur dioxide” puede haberlos. Nos ayudaremos de diagramas de caja.
sb.boxplot(x=vinos["residual sugar"])
sb.boxplot(x=vinos["free sulfur dioxide"])
sb.boxplot(x=vinos["total sulfur dioxide"])
Tras visualizar es tas distribuciones se borran los registros con los valores que he considerado anómalos por encontrarse muy separados del resto de muestras.
vinos.drop(vinos[vinos["residual sugar"]>60].index,inplace = True)
vinos.drop(vinos[vinos["free sulfur dioxide"]>200].index,inplace = True)
vinos.drop(vinos[vinos["total sulfur dioxide"]>400].index,inplace = True)
En el siguiente bloque vamos a transformar las variables “quality” a categórica y “PH a booleana para cumplir con los requisitos mínimos de la práctica. Las categorías de quality se han reducido a tres; y están centradas en los valores enteros originales más frecuentes: 5, 6 y 7.
Por otro lado vamos a seleccionar la variable “total sulfur dioxide” para discretizarla, dado que presenta la distribución con mayor dispersión.
Tomaremos como referencia los cuantiles: 0,% 20%, 40%, 60%,80% y 100%, que marcarán cinco intervalos.
A cada valor se le asignará el valor medio del intervalo al que pertenezca.
calidad_cat=vinos["quality"].copy()
calidad_cat[(vinos["quality"]<=5)]="baja"
calidad_cat[vinos["quality"]==6]="media"
calidad_cat[vinos["quality"]>=7]="alta"
vinos["quality"]=calidad_cat
media_ph=statistics.mean(vinos["pH"])
ph_bin=pd.cut(vinos.pH, [-100,media_ph,100], labels=[False,True])
vinos["pH"]=np.array(ph_bin).astype('bool').tolist()
media_intervalos=[]
for i in [0,0.2,0.4,0.6,0.8,1]:
if(i>0):
media_intervalos.append((vinos["total sulfur dioxide"].quantile(i)+vinos["total sulfur dioxide"].quantile(i-0.2))/2)
pd.qcut(vinos["total sulfur dioxide"],q=5)
## 0 (165.0, 366.5]
## 1 (105.0, 132.0]
## 2 (62.0, 105.0]
## 3 (165.0, 366.5]
## 4 (165.0, 366.5]
## ...
## 6492 (5.999, 62.0]
## 6493 (5.999, 62.0]
## 6494 (5.999, 62.0]
## 6495 (5.999, 62.0]
## 6496 (5.999, 62.0]
## Name: total sulfur dioxide, Length: 6495, dtype: category
## Categories (5, interval[float64]): [(5.999, 62.0] < (62.0, 105.0] < (105.0, 132.0] < (132.0, 165.0] <
## (165.0, 366.5]]
tsd_disc=pd.qcut(vinos["total sulfur dioxide"],q=5,labels=[media_intervalos[0],media_intervalos[1],media_intervalos[2],media_intervalos[3],media_intervalos[4]])
vinos["total sulfur dioxide"]=np.array(tsd_disc).astype('float').tolist()
vinos.to_csv("D:\\uoc\\mineria de datos\\PRA2\\out.csv", index=False)
Ahora vamos a visualizar mediante un mapa de calor las correlaciones entre las distintas variables. Ya en la URL de donde se han tomado los datasets originales nos adelantaban que probablemente se puedan prescindir de algunas de las características.
En general se aprecian niveles de correlación moderados. Solo encontramos un índice de correlación moderado entre ““type” y “volatile acidity” y entre “total sulfur dioxide” y “free sulfur dioxide”. Destaca también una correlación negativa moderada entre “density” y “alcochol”
sb.heatmap(vinos.corr(), cmap="YlGnBu", annot=True)
En primer lugar normalizamos todas las variables
X = vinos.iloc[:,0:12].values
X_std = StandardScaler().fit_transform(X)
X_std
## array([[-0.57148328, -0.1661387 , -0.42308539, ..., -0.96563998,
## -0.54588774, -1.41829489],
## [-0.57148328, -0.7060791 , -0.24067379, ..., 1.03558264,
## -0.27706723, -0.83139582],
## [-0.57148328, 0.68233906, -0.36228152, ..., 1.03558264,
## -0.61309287, -0.32833947],
## ...,
## [ 1.74983248, -0.7060791 , 1.03620745, ..., 1.03558264,
## 1.47026606, 0.42624505],
## [ 1.74983248, -1.01461647, 1.85705967, ..., 1.03558264,
## 1.20144555, -0.24449675],
## [ 1.74983248, -0.93748213, -0.17986992, ..., 1.03558264,
## 0.86541992, 0.42624505]])
Invocamos la función sk_pca con la opción svd_solver a “full” que realiza la descomposición en valores singulares truncada al numero de componentes pasado como parámetro.
Para ver la cantidad de información que aporta cada componente a la varianza explicada hacemos un gráfico de la varianza explicada acumulada. Se aprecia un punto de inflesion para 9 componentes
acp = sk_pca(n_components=12,svd_solver="full")
Y = acp.fit_transform(X_std)
plt.xlabel('numero de componentes')
plt.ylabel('Varianza explicada acumulada');
plt.plot(np.cumsum(acp.explained_variance_ratio_))
Efectivamente con esos 9 componentes casi alcanzamos el 96% de la varianza explicada. Vamos a quedaros con esas y descaramos al resto
print(np.cumsum(acp.explained_variance_ratio_ *100)[8])
## 95.9900653031772
Finalmente hacemos gráficas para comparar de dos en dos los componentes principales elegidos.
Las distribuciones de las categorías de vino en todos lo caso siguen distribuciones que parecidas a una distribución normal
El problema es que las categoría “normal” engloba al resto de distribuciones lo cal pued dar problemas
vinos_PCA=pd.DataFrame(Y[:,0:9],columns=["CP1","CP2","CP3","CP4","CP5","CP6","CP7","CP8","CP9"])
vinos_PCA["quality"]=vinos["quality"]
vinos_PCA.to_csv("D:\\uoc\\mineria de datos\\PRA2\\vinos_PCA.csv", index=False)
Por último vamos a comparar dos gráficas compuestas: - La primera refleja la dispersión de los componentes principales tomadas de par en par junto con la distribución que siguen los valores de la variable “quality” para cada par de componentes principales. La distribución de puntos refleja el bajísimo nivel de correlación si bien no se aprecia una separación clara entre los distintos valores quality
#sb.pairplot(vinos_PCA,hue="quality")
#sb.pairplot(vinos,hue="quality")
Vamos a hacer otra prueba alterativa para descartar que el hecho de haber perdido información al hacer binaria la variable PH o al haber introducido la variable “arificla” “type” haya podido alterar la información relevante del juego de datos. Rpetriemos el proceso anterior pero sin esas dos variables y y resultando en un juego de 8 componentes principales que siguen teineindo por encima del 95% de la varianza explicativa acumulada.
vinos=vinos.drop(["pH","type"],axis=1)
X = vinos.iloc[:,0:10].values
X_std = StandardScaler().fit_transform(X)
acp = sk_pca(n_components=10,svd_solver="full")
Y = acp.fit_transform(X_std)
acp.explained_variance_ratio_
## array([0.28443975, 0.24980949, 0.13682342, 0.08741189, 0.0640728 ,
## 0.0572703 , 0.04976371, 0.0353938 , 0.02869782, 0.00631702])
print(np.cumsum(acp.explained_variance_ratio_ *100)[7])
## 96.49851673105935
vinos_PCA=pd.DataFrame(Y[:,0:8],columns=["CP1","CP2","CP3","CP4","CP5","CP6","CP7","CP8"])
vinos_PCA["quality"]=vinos["quality"]
sb.pairplot(vinos_PCA,hue="quality")
Comprobamos que gráficamente no se observa una diferencia significativa con el resultado anterior. En principio podríamos optar por este juego de características también pero seguiremos manteniendo el anterior ya que esta prueba alternativa era simplemente por descartar que la alteración del dataset original para cumplir con los requisitos mínimos exigidos por la práctica hubiese supuesto un cambio profundamente contraproducente.
##conclusión
Como conclusión final se puede sacar es que tras haber hecho todas las transformaciones pertinentes de los datasets original se prevé que encontrar un modelo de clasificación con un nivel de precisión objetivo puede ser complicado. Si bien con el uso de PCA-SVD se ha reducido la dimensionalidad y bajado la correlación ente atributos, sigue observándose un solapamiento excesivo de las distintas calidades de los vinos. Hay que tener en cuenta que el modelo referenciado en la bibliografía se usaron modelos potentes y sofisticados, con SVD. Eso no quiere decir que sea este dataset apto para otros métodos, ya que en en el archivo de datasets donde se encuentra disponible lo catalogan como válido para aplicar modelos de clasificación en general.
En cualquier caso se ha simplificado las categorías a 3 para hacer la tare más sencilla y se seguirá adelante con la elaboración del modelo tal que como se ha establecido al principio.
[Archivo de datasets] https://archive.ics.uci.edu/ml/datasets/Wine+Quality
[Paper del modelos de regresiones y SVM para “Vinho verde”] https://www.sciencedirect.com/science/article/abs/pii/S0167923609001377?via%3Dihub